package main

import (
	"bytes"
	"embed"
	"fmt"
	"image"
	_ "image/jpeg" // 支持JPEG格式
	"syscall"
	"time"

	_ "image/png" // 支持PNG格式

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
	"github.com/lxn/win"
)

//go:embed icon.jpg
var iconFS embed.FS

func main() {
	// 创建主窗口
	var mainWindow *walk.MainWindow
	var label *walk.Label
	var notifyIcon *walk.NotifyIcon // 系统托盘图标 (稍后初始化)
	var isTopmost bool = true       // 默认开启置顶
	var (                           // 拖拽相关变量
		isDragging bool
		dragStartX int
		dragStartY int
	)

	// 倒计时设置
	countdownSeconds := 3 * 60 // 3分钟
	currentSeconds := countdownSeconds
	var timer *time.Ticker
	isRunning := true // 默认开始倒计时

	// 格式化时间为分:秒格式
	formatTime := func(seconds int) string {
		minutes := seconds / 60
		s := seconds % 60
		return fmt.Sprintf("%02d:%02d", minutes, s)
	}

	// 定义应用程序的主窗口和UI元素，使用SpacingZero减少间距
	err := MainWindow{
		AssignTo: &mainWindow,
		Title:    "打坐倒计时",
		Size:     Size{Width: 100, Height: 30}, // 窗口基础大小
		Layout:   HBox{SpacingZero: true},      // 零间距布局
		Children: []Widget{
			// 显示时间
			Label{
				AssignTo:  &label,
				Text:      formatTime(currentSeconds),
				Font:      Font{PointSize: 16, Bold: true}, // 使用16点字体
				Alignment: AlignHCenterVCenter,
			},
		},
	}.Create()

	if err != nil {
		panic(err)
	}

	// 移除最大化和最小化按钮
	hwnd := win.HWND(mainWindow.Handle())
	style := win.GetWindowLong(hwnd, win.GWL_STYLE)
	style &^= win.WS_MINIMIZEBOX
	style &^= win.WS_MAXIMIZEBOX
	// 移除标题栏
	style &^= win.WS_CAPTION
	style &^= win.WS_BORDER
	style &^= win.WS_THICKFRAME
	win.SetWindowLong(hwnd, win.GWL_STYLE, style)
	// 重置窗口大小以确保紧凑显示
	win.SetWindowPos(hwnd, 0, 0, 0, 100, 30, win.SWP_NOMOVE|win.SWP_NOZORDER|win.SWP_FRAMECHANGED)

	// 设置窗口透明背景
	// 定义需要的常量
	const (
		WS_EX_LAYERED = 0x80000
		LWA_ALPHA     = 0x00000002
	)
	extendedStyle := win.GetWindowLongPtr(hwnd, win.GWL_EXSTYLE)
	extendedStyle |= WS_EX_LAYERED
	win.SetWindowLongPtr(hwnd, win.GWL_EXSTYLE, extendedStyle)

	// 默认开启置顶
	if isTopmost {
		win.SetWindowPos(hwnd, win.HWND_TOPMOST, 0, 0, 0, 0, win.SWP_NOMOVE|win.SWP_NOSIZE)
	}

	// 创建系统托盘图标
	notifyIcon, err = walk.NewNotifyIcon(mainWindow)
	if err != nil {
		panic(err)
	}

	// 设置托盘图标属性
	// 从嵌入的文件系统中加载图标
	iconData, err := iconFS.ReadFile("icon.jpg")
	if err != nil {
		walk.MsgBox(mainWindow, "警告", "无法读取嵌入的图标文件: "+err.Error(), walk.MsgBoxIconWarning)
	} else {
		// 解码JPEG图像
		img, _, err := image.Decode(bytes.NewReader(iconData))
		if err != nil {
			walk.MsgBox(mainWindow, "警告", "无法解码图标图像: "+err.Error(), walk.MsgBoxIconWarning)
		} else {
			// 创建图标
			icon, err := walk.NewIconFromImageForDPI(img, 96) // 96 DPI 是标准Windows DPI
			if err != nil {
				walk.MsgBox(mainWindow, "警告", "无法创建托盘图标: "+err.Error(), walk.MsgBoxIconWarning)
			} else {
				notifyIcon.SetIcon(icon)
			}
		}
	}
	notifyIcon.SetToolTip("打坐倒计时")

	// 显示托盘图标
	if err := notifyIcon.SetVisible(true); err != nil {
		panic(err)
	}

	// 添加鼠标点击事件处理
	notifyIcon.MouseDown().Attach(func(x, y int, button walk.MouseButton) {
		if button == walk.LeftButton {
			// 左键点击：切换主窗口显示/隐藏
			if mainWindow.Visible() {
				mainWindow.Hide()
			} else {
				mainWindow.Show()
				// 确保窗口在最前面
				mainWindow.SetFocus()
			}
		} else if button == walk.RightButton {
			// 右键点击：直接显示退出确认对话框
			result := walk.MsgBox(mainWindow, "退出确认", "确定要退出程序吗？", walk.MsgBoxYesNo|walk.MsgBoxIconQuestion)
			if result == walk.DlgCmdYes {
				mainWindow.Close()
			}
		}
	})

	// 定义Windows API常量
	const (
		WM_HOTKEY = 0x0312
		MOD_NONE  = 0
		VK_F7     = 0x76
		HOTKEY_ID = 1
	)

	// 获取user32.dll库
	user32 := syscall.NewLazyDLL("user32.dll")
	registerHotKey := user32.NewProc("RegisterHotKey")
	unregisterHotKey := user32.NewProc("UnregisterHotKey")
	// 设置窗口透明度
	setLayeredWindowAttributes := user32.NewProc("SetLayeredWindowAttributes")
	// 设置透明度（255为不透明，0为完全透明）
	// 设置为180，这样既能看到下方窗口内容，又能清晰显示倒计时
	setLayeredWindowAttributes.Call(uintptr(hwnd), uintptr(0), uintptr(180), uintptr(LWA_ALPHA))

	// 注册全局热键 F7
	hotkeyRegistered := false
	ret, _, _ := registerHotKey.Call(uintptr(hwnd), uintptr(HOTKEY_ID), uintptr(MOD_NONE), uintptr(VK_F7))
	hotkeyRegistered = ret != 0

	if !hotkeyRegistered {
		walk.MsgBox(mainWindow, "错误", "无法注册全局热键 F7", walk.MsgBoxIconError)
	}

	// 定义F7键重置功能
	resetCountdown := func() {
		if isRunning {
			if timer != nil {
				timer.Stop()
			}
		}
		currentSeconds = countdownSeconds
		label.SetText(formatTime(currentSeconds))
		isRunning = true
		timer = time.NewTicker(1 * time.Second)

		go func() {
			for {
				select {
				case <-timer.C:
					if currentSeconds > 0 {
						currentSeconds--
						mainWindow.Synchronize(func() {
							label.SetText(formatTime(currentSeconds))
						})
					} else {
						// 倒计时结束
						timer.Stop()
						mainWindow.Synchronize(func() {
							label.SetText(formatTime(currentSeconds))
							isRunning = false
						})
						return
					}
				}
			}
		}()
	}

	// 默认开始倒计时
	if isRunning {
		resetCountdown()
	}

	// 定义WNDPROC类型
	type WNDPROC func(win.HWND, uint32, uintptr, uintptr) uintptr

	// 使用Windows API直接设置窗口过程来捕获热键事件
	var oldWndProc uintptr

	// 获取当前窗口过程
	oldWndProc = win.GetWindowLongPtr(hwnd, win.GWL_WNDPROC)

	// 设置新的窗口过程，只处理热键事件
	newWndProc := func(hwnd win.HWND, msg uint32, wParam, lParam uintptr) uintptr {
		if msg == WM_HOTKEY && wParam == uintptr(HOTKEY_ID) {
			// F7键被按下，重置倒计时
			mainWindow.Synchronize(func() {
				resetCountdown()
			})
			return 0
		}
		// 调用原始窗口过程
		return win.CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam)
	}

	// 设置新的窗口过程
	win.SetWindowLongPtr(hwnd, win.GWL_WNDPROC, syscall.NewCallback(newWndProc))

	// 添加鼠标按下事件处理
	mainWindow.MouseDown().Attach(func(x, y int, button walk.MouseButton) {
		if button == walk.LeftButton {
			isDragging = true
			dragStartX = x
			dragStartY = y
		}
	})

	// 添加鼠标抬起事件处理
	mainWindow.MouseUp().Attach(func(x, y int, button walk.MouseButton) {
		if button == walk.LeftButton {
			isDragging = false
		}
	})

	// 添加鼠标移动事件处理
	mainWindow.MouseMove().Attach(func(x, y int, button walk.MouseButton) {
		if isDragging {
			// 获取当前窗口位置
			windowX, windowY := mainWindow.X(), mainWindow.Y()
			// 计算新位置
			newX := windowX + (x - dragStartX)
			newY := windowY + (y - dragStartY)
			// 移动窗口
			mainWindow.SetX(newX)
			mainWindow.SetY(newY)
		}
	})

	// 程序退出时释放资源
	mainWindow.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
		if timer != nil {
			timer.Stop()
		}
		if hotkeyRegistered {
			unregisterHotKey.Call(uintptr(hwnd), uintptr(HOTKEY_ID))
		}
		// 恢复原始窗口过程
		win.SetWindowLongPtr(hwnd, win.GWL_WNDPROC, oldWndProc)
		// 释放托盘图标
		if notifyIcon != nil {
			notifyIcon.Dispose()
		}
	})

	// 运行应用程序
	mainWindow.Run()
}
